/*
 * $RCSfile: Recovery.java,v $$
 * $Revision: 1.1 $
 * $Date: 2013-12-15 $
 *
 * Copyright (C) 2008 Skin, Inc. All rights reserved.
 *
 * This software is the proprietary information of Skin, Inc.
 * Use is subject to license terms.
 */
package com.skin.webcat.exchange;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.sql.Connection;
import java.sql.SQLException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * <p>Title: Recovery</p>
 * <p>Description: </p>
 * <p>Copyright: Copyright (c) 2006</p>
 * @author xuesong.net
 * @version 1.0
 */
public class Recovery implements Runnable {
    private String target;
    private Connection connection = null;
    private static final Logger logger = LoggerFactory.getLogger(Recovery.class);

    /**
     * @param connection
     * @param target
     */
    public Recovery(Connection connection, String target) {
        this.target = target;
        this.connection = connection;
    }

    /**
     * @param connection
     * @param target
     * @throws Exception
     */
    public static void execute(Connection connection, File target) throws Exception {
        if(logger.isInfoEnabled()) {
            logger.info("Recovery start...");
            logger.info("Recovery.target: " + target.getAbsolutePath());
        }

        Exception exception = null;
        File lock = new File(target, "LOCK");

        if(lock.exists() == false) {
            try {
                lock.createNewFile();
                File[] files = target.listFiles();

                if(files != null) {
                    for(File file : files) {
                        if(file.getName().toLowerCase().endsWith(".txt")) {
                            if(logger.isInfoEnabled()) {
                                logger.info("import " + file.getAbsolutePath());
                            }

                            recovery(connection, file);
                        }
                    }
                }
            }
            catch(Exception e) {
                exception = e;
            }

            try {
                lock.delete();
            }
            catch(Exception e) {
                e.printStackTrace();
            }
        }
        else {
            if(logger.isInfoEnabled()) {
                logger.info("Recovery is running...");
            }
        }

        if(logger.isInfoEnabled()) {
            logger.info("Recovery complete !");
        }

        if(exception != null) {
            throw exception;
        }
    }

    /**
     * @param connection
     * @param file
     * @throws Exception
     */
    public static void recovery(Connection connection, File file) throws Exception {
        InputStream inputStream = null;
        InputStreamReader reader = null;

        try {
            inputStream = new FileInputStream(file);
            reader = new InputStreamReader(inputStream, "UTF-8");
            DataImport dataImport = new DataImport();
            DefaultHandler defaultHandler = new DefaultHandler(connection);
            dataImport.setProcessHandler(defaultHandler);
            dataImport.execute(reader, 500, true);
        }
        catch(Exception e) {
            throw new Exception("Exception at: " + file.getAbsolutePath(), e);
        }
    }

    /**
     * run
     */
    @Override
    public void run() {
        try {
            Recovery.execute(this.connection, new File(this.target));
        }
        catch(Throwable t) {
            t.printStackTrace();
        }
        finally {
            if(this.connection != null) {
                try {
                    this.connection.close();
                }
                catch(SQLException e) {
                }
            }
        }
    }

    /**
     * @return the target
     */
    public String getTarget() {
        return this.target;
    }

    /**
     * @param target the target to set
     */
    public void setTarget(String target) {
        this.target = target;
    }

    /**
     * @return the connection
     */
    public Connection getConnection() {
        return this.connection;
    }

    /**
     * @param connection the connection to set
     */
    public void setConnection(Connection connection) {
        this.connection = connection;
    }
}
